package com.leador.socket;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.leador.assist.DataQueueManager;
import com.leador.core.Trace;
import com.leador.jni.TraceJniInterface;
import com.leador.service.LBSTraceService;
import com.leador.socket.listener.SoConnectListener;
import com.leador.utils.TraceSeleGenre;

import java.io.DataInputStream;

/**
 * Created by lhy on 2016/9/14.
 */
public class SocketMananger implements SoConnectListener{
    public SocketConnect socketConnect = null;
    public SocketThread socketThread = null;
    public ReadThread readThread = null;
    public WriteThread writeThread = null;
    public Handler handler = null;
    private static SocketMananger INSTANCE = null;
    private boolean socketReadEnable = false;
    private LBSTraceService lbsTraceService;
    public final Object writeLock = new Object();
    private boolean socketStart = false;
    public boolean socketCast = false;
    private SocketMananger(LBSTraceService lbsTraceService){
        this.lbsTraceService = lbsTraceService;
        socketConnect = new SocketConnect(this);
        this.handler = lbsTraceService.getLbsServiceHandler();
    }

    public static SocketMananger getInstance(LBSTraceService lbsTraceService){
        if(INSTANCE == null){
            synchronized (SocketMananger.class){
                if(INSTANCE == null){
                    INSTANCE = new SocketMananger(lbsTraceService);
                }
            }
        }
        return INSTANCE;
    }

    /**
     * 1.开启socket连接
     */
    public void startSocketConnect(){
        if(socketStart || TraceSeleGenre.NOT_DATA_SOCKET_CONNECT.getValue() == Trace.traceType){
            return;
        }
        socketStart = true;
        if(socketThread != null){
            socketThread = null;
        }
        socketThread = new SocketThread(this);
        socketThread.start();
    }

    //TODO 暂时没有作用(用于推送使用)
    /**
     * 2.开启Socket读线程
     * @return
     */
    public boolean startReadConnect(){
        if(socketReadEnable){
            return true;
        }
        if(socketConnect == null){
            return false;
        }
        if(socketConnect.socketIsConnect()){
            if (this.handler != null) {
                this.handler.obtainMessage(4).sendToTarget();
            }
            return false;
        }
        socketReadEnable = true;
        readThread = new ReadThread(this);
        readThread.start();
        return true;
    }

    /**
     * 3.socket写入
     * @param bytes
     */
    public void writeTConnect(byte[] bytes){
        if(writeThread != null){
            writeThread = null;
        }
        writeThread = new WriteThread(this,bytes);
        writeThread.start();
    }

    /**
     * 4.发送数据
     * @return 是否成功
     */
    public boolean sendData(){
        if(socketConnect == null){
            Log.e("socketConnect","is null");
        }
        byte[] buildPackData = DataQueueManager.getInstance().setSendDataQueue(lbsTraceService.getContext());
        if (buildPackData.length > 0){
            if(writeThread == null){
                writeThread = new WriteThread(this,null);
            }
            //TODO 将即将写入的数据加入到 uploadingDatas里面去。
            DataQueueManager.getInstance().removeSendData();
            writeThread.writeOutputStream(buildPackData,lbsTraceService.getLbsServiceHandler());
            writeThread = null;
            return true;
        }else{
            //将数据加入到缓存中
            DataQueueManager.getInstance().sendToTempQueue();
            return false;
        }


    }

    /**
     * 5.发送心跳包
     */
    public void sendHeartData(){
        if(socketConnect == null){
            Log.e("socketConnect","is null");
        }

        //TODO send heart data
        byte[] heartData = TraceJniInterface.buildHeartbeatData();
        if (heartData == null){
            Log.e("heartData","heartData is null");
            return;
        }
        //TODO 心跳包暂时不发
        //发送心跳包
//        writeThread.writeOutputStream(heartData,lbsTraceService.getLbsServiceHandler());
    }

    /**
     * 6.断开连接
     */
    public void disSocketConnect(){
        if(socketStart){
            socketStart = false;
        }
        disconnect();
    }

    /**
     * 7.socket 连接
     */
    public void connect(){
        if(socketConnect == null){
            return;
        }
        socketConnect.connect();
    }

    /**
     * 8.断开socket
     */
    public void disconnect(){
        if(socketThread != null){
            socketThread.setConnectEnable(false);
        }

        //停止读
        if(socketReadEnable){
            socketReadEnable = false;
            if(null == readThread){
                return;
            }
            readThread.setReadEnable(false);
        }

        //释放资源
        writeThread = null;

        //关闭socket
        if(socketConnect != null){
            socketConnect.disconnectSocket();
        }
    }

    public Handler getHandler() {
        return handler;
    }

    /**
     * 获取DataInputStream
     * @return
     */
    public DataInputStream getDataInputStream(){
        return socketConnect.getDataInputStram();
    }

    /**
     * 上报数据 写入
     */
    public void wirteContent(byte[] bytes){
         socketConnect.writeOutputStream(bytes,handler);
    }

    @Override
    public void connectSucess() {
        if(socketThread == null){
            return;
        }
        //禁止重连
        socketThread.setConnectEnable(false);
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        Message message = handler.obtainMessage(1);
        message.sendToTarget(); //连接成功
    }

    @Override
    public void disconnectSucess() {
        Log.e("disconnectSucess is","disconnectSucess");
        int reConnectTime = getReConnectTime();
        if(reConnectTime>0){
            reConnect();
            return;
        }
        socketThread.setConnectEnable(false);
        Message message = handler.obtainMessage(19);
        message.sendToTarget(); //连接失败停止重连
    }



    @Override
    public void failure(String message) {

    }

    private int reConnectTime  = 30; //重连次数
    public void reConnect(){
        //rclose
        disSocketConnect();
        reConnectTime -= -1;
        try {
            Thread.sleep(6000L);
            return;
        } catch (InterruptedException exception) {

        }
    }

    public int getReConnectTime() {
        return reConnectTime;
    }

}
